package cn.ococci.dm.Main.Core;

import android.os.SystemClock;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.List;

import cn.ococci.dm.Main.Const;
import cn.ococci.dm.Main.OtaType;
import cn.ococci.dm.Main.Tools.LogTool;
import cn.ococci.dm.Main.Tools.StringTool;

/**
 * Created by cyan on 15/12/29.
 */
public class SocketCommand {

    public static final String TAG = SocketCommand.class.getSimpleName();

    private CommandStatusCallback commandCallback;

    public CommandType commandType;

    private Socket socket = null;
    private BufferedReader reader = null;
    private DataOutputStream doc = null;

    //OTA版本升级
    private boolean loop = true;
    public String localVersion;
    private OtaType otaType = OtaType.NONE;


    public SocketCommand(CommandStatusCallback callback) {
        this.commandCallback = callback;
    }

    private void initSocket() {
        socket = new Socket();
        SocketAddress  address = new InetSocketAddress(Const.IP, Const.PORT);
        try {
            socket.connect(address, Const.TIME_OUT);

            commandCallback.startExecuteCommand();
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            doc = new DataOutputStream(socket.getOutputStream());
        } catch (IOException e) {
            LogTool.log(TAG, "init socket:"+e.getMessage());
            commandCallback.failureExecuteCommand();
            e.printStackTrace();
        }
    }


    /**
     * 关闭所有的操作对象，以及设置一个是否完成的标志位：hasFinish
     *
     * @param reader
     * @param doc
     */
    private void close(BufferedReader reader, DataOutputStream doc) {
        try {
            if (doc != null) {
                doc.close();
            }

            LogTool.log(TAG,"程序开始断开连接....");

            if (reader != null) {
                reader.close();
            }

            if (socket != null) {
                socket.close();
                socket = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private void handlerReceiverData(final BufferedReader reader) {

        char[] cha = new char[1024];
        String content;
        try {
            reader.read(cha);
            content = new String(cha, 0, cha.length);
            int lastLength = content.lastIndexOf("}");
            content = content.substring(0, lastLength + 1);

            LogTool.log(TAG, "接收的内容是:" + content);

            switch (commandType) {
                case COMMAND_ADD_WHITE:

                    if (DecodeCommandUtils.isSetWhiteListSuccess(content)) {
                        commandCallback.successExecuteCommand();
                    } else {
                        commandCallback.failureExecuteCommand();
                    }
                    break;
                case COMMAND_ADD_BlACK:
                    break;

                case COMMAND_OTA_VERSION:
                     // 解析固件的版本数据
                    String[] versions = DecodeCommandUtils.handlerOtaVersion(content);
                    handlerOTAVersion(versions);

                    break;
                case INFRARED_STATUS:
                    commandCallback.successForInfrared(DecodeCommandUtils.handlerInfraredResult(content));

                    break;

                default:
                    LogTool.error(TAG, "未知的命令Code:" + commandType.type);
                    commandCallback.failureExecuteCommand();
                    break;
            }
        } catch (IOException e) {
            commandCallback.failureExecuteCommand();
            LogTool.log(TAG, "读取内容异常:" + e.toString());
        }
    }


    /**
     * 新增白名单或者黑名单
     * @param commandType
     * @param ids
     */
    public void addWhiteBlackList(CommandType commandType, List<Integer> ids) {
        this.commandType = commandType;
        initSocket();
        try {

            String firstCommand = EncodeCommandUtils.builderWhiteList(ids, commandType == CommandType.COMMAND_ADD_WHITE);
            doc.write(firstCommand.getBytes());  //写入命令
            doc.flush();
            handlerReceiverData(reader);
        } catch (Exception e) {
            commandCallback.failureExecuteCommand();
            LogTool.log(TAG, "异常信息：" + e.toString());
            e.printStackTrace();
        } finally {
            close(reader, doc);
        }
    }


    public void getOtaVersion(CommandType commandType){

        this.commandType = commandType;
        initSocket();
        try {

            String firstCommand = EncodeCommandUtils.builderOTAVersion();
            doc.write(firstCommand.getBytes());  //写入命令
            doc.flush();
            handlerReceiverData(reader);
        } catch (Exception e) {
            commandCallback.failureExecuteCommand();
            LogTool.log(TAG, "异常信息：" + e.toString());
            e.printStackTrace();
        } finally {

            close(reader, doc);
        }

    }

    // 不断的去检测版本.直到版本等于当前的版本之后。退出
    public void loopOtaVersion(CommandType commandType,OtaType otaType,String localVersion){
        this.localVersion = localVersion;
        this.commandType = commandType;
        this.otaType = otaType;

        while (loop){
            initSocket();
            try {

                String firstCommand = EncodeCommandUtils.builderOTAVersion();
                doc.write(firstCommand.getBytes());  //写入命令
                doc.flush();
                handlerReceiverData(reader);
            } catch (Exception e) {
                commandCallback.failureExecuteCommand();
                LogTool.log(TAG, "异常信息：" + e.toString());
                e.printStackTrace();
            } finally {
                close(reader, doc);
            }
            SystemClock.sleep(2000);
        }
        commandCallback.successForSingleOtaVersion(localVersion);
    }


    private void handlerOTAVersion(String[] versions){

        switch (otaType){
            case NONE:
                commandCallback.successForOtaVersion(versions);
                break;

            case OTC_AP:

                if(StringTool.compareEqualsVersion(versions[0],localVersion)){
                    breakLoop();
                }
                break;
            case OTC_PR:

                if(StringTool.compareEqualsVersion(versions[1],localVersion)){
                    breakLoop();
                }
                break;
        }
    }

    public void openInfrared(CommandType commandType,boolean isOn){
        this.commandType = commandType;
        initSocket();
        try {

            String firstCommand = EncodeCommandUtils.builderOpenInfrared(isOn);
            doc.write(firstCommand.getBytes());  //写入命令
            doc.flush();
            commandCallback.successExecuteCommand();
        } catch (Exception e) {
            commandCallback.failureExecuteCommand();
            LogTool.log(TAG, "异常信息：" + e.toString());
            e.printStackTrace();
        } finally {
            close(reader, doc);
        }

    }

    public void getInfraredStatus(CommandType commandType){
        this.commandType = commandType;
        initSocket();
        try {

            String firstCommand = EncodeCommandUtils.builderInfraredStatus();
            doc.write(firstCommand.getBytes());  //写入命令
            doc.flush();
            handlerReceiverData(reader);
        } catch (Exception e) {
            commandCallback.failureExecuteCommand();
            LogTool.log(TAG, "异常信息：" + e.toString());
            e.printStackTrace();
        } finally {
            close(reader, doc);
        }

    }







    /**
     * 中断获取ota版本
     */
    public void breakLoop(){
        this.loop = false;
    }



//
//    /**
//     * 设置信号强度
//     *
//     * @param commandType
//     */
//    public void setValidLeverCommand(CommandType commandType, int lever) {
//        this.commandType = commandType;
//        initSocket();
//        try {
//            //设置信号强度
//            String firstCommand = EncodeCommandUtils.buildValidLever(lever);
//            doc.write(firstCommand.getBytes());  //写入命令
//            doc.flush();
//            startServerReplyListener(reader);
//        } catch (Exception e) {
//
//            e.printStackTrace();
//        } finally {
//            close(reader, doc);
//        }
//
//    }
//
//
//
//    /**
//     * 修改系统时间
//     *
//     * @param commandType
//     */
//    public void modifyDoorSystemTime(int commandType) {
//        this.commandType = commandType;
//        initSocket();
//        try {
//            String modifyTimeCommand = EncodeCommandUtils.builderSystemTime();
//            doc.write(modifyTimeCommand.getBytes());
//            doc.flush();
//            startServerReplyListener(reader);
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            close(reader, doc);
//        }
//    }
//
//    /**
//     * 获取门禁中所有的打卡记录
//     *
//     * @param commandType
//     */
//    public void obtainWholeRecord(int commandType) {
//        this.commandType = commandType;
//        initSocket();
//        try {
//            String wholeRecordCommand = EncodeCommandUtils.builderWholeRecord();
//            doc.write(wholeRecordCommand.getBytes());
//            doc.flush();
////            receiverWholeRecord(reader);
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            close(reader, doc);
//        }
//    }
//
//    /**
//     * 清除门禁系统的所有记录数
//     *
//     * @param commandType
//     */
//    public void clearWholeWhiteRecord(int commandType) {
//        this.commandType = commandType;
//        initSocket();
//        try {
//            String wholeRecordCommand = EncodeCommandUtils.builderWholeRecord();
//            doc.write(wholeRecordCommand.getBytes());
//            doc.flush();
////            receiverWholeRecord(reader);
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            close(reader, doc);
//        }
//
//    }
//
//    /**
//     * 设置当前模式为混杂模式
//     */
//    public void modifyCurModelWithMixModel(int commandType) {
//        this.commandType = commandType;
//        try {
//            String wholeRecordCommand = EncodeCommandUtils.builderSetMixModel();
//            doc.write(wholeRecordCommand.getBytes());
//            doc.flush();
////            receiverWholeRecord(reader);
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            close(reader, doc);
//        }
//
//    }
//

    //-----------------------------------------------------------

    /**
     * 读取从门禁中返回的所有记录数据
     *
     * @param reader
     */
//    private void receiverWholeRecord(final BufferedReader reader) {
//        char[] cha = new char[1024];
//        List<Record> data = null;
//        try {
//            while (reader.read(cha) != -1) {
//
//                String content = new String(cha, 0, cha.length);
//                if (!StringTool.isEmpty(content)) {
//                    int lastLength = content.lastIndexOf("}");
//                    content = content.substring(0, lastLength + 1);
//                    LogTool.log(TAG, "接收的内容是:" + content);
//                    JsonObject jsonObject = Json.parseObject(content);
//
//                    if (!jsonObject.containsKey(Const.CommandParams.COMMAND_TYPE)) {
//                        //结束
//                        if (data == null) {
//                            data = new ArrayList<>();
//                        }
//                        data.add(Convert.jsonToRecord(jsonObject,uniqueIdentificationWithDoor));
//                    } else {
//                        break;
//                    }
//                }
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        if (StringTool.hasData(data)) {
//            this.statusCallback.onSuccessReturnList(data);
//        }else{
//            this.statusCallback.onFailure(Const.BIZ_ERROR);
//        }
//
//    }


//    /**
//     * 解析核心命令数据
//     *
//     * @param content
//     * @param jsonObject
//     */
//    private void decodeMainCommand(String content, JsonObject jsonObject) {
//        if (jsonObject.containsKey(Const.CommandParams.COMMAND_OPEN_RESULT)) {  // Open DoorModel
//            Record record = Convert.decodeDoorStatusCommand(jsonObject);  //这里只有一个时间
//            if (record != null) {
//                record.setPhoneMacId(uniqueIdentificationWithPhone); //打卡人手机的唯一标识
//                record.setDoorMac(uniqueIdentificationWithDoor);  //门禁mac
//                record.setCompanyId(CurUser.getCompanyId());  //公司id
//                statusCallback.onSuccessOpen(record);  //这里后期需要处理
//            } else {
//                statusCallback.onFailure(Const.BIZ_ERROR);
//            }
//            hasFinish = true;
//
//        } else {
//            statusCallback.onDoorReplyLever(DecodeCommandUtils.decodeSignalCommand(content));  //获取到信号强度
//        }
//    }

//
//    /**
//     * 保存wifi
//     *
//     * @param commandType
//     */
//    public void startSaveWifiCommand(CommandType commandType) {
//        this.commandType = commandType;
//        initSocket();
//        try {
//            //发送获取信号强度的命令
//            String firstCommand = EncodeCommandUtils.buildWifiCommand(csq[0], csq[1]);  //构建发送(BSSID,以及pwd)
//            doc.write(firstCommand.getBytes());  //写入命令
//            doc.flush();
//            startServerReplyListener(reader);
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            close(reader, doc);
//        }
//    }


//    switch (commandType) {
//        case COMMAND_ADD_WHILTE:
//
//            break;
//        case Const.DoorCommandType.COMMAND_SAVE_WIFI:   //设置wifi
//            boolean success = jsonObject.getBoolean(Const.DoorWifi.COMMAND_WIFI_RETURN_RESULT);
//            if (success) {
////                        this.statusCallback.onSuccess();
//            } else {
////                        this.statusCallback.onFailure(Const.WIFI_BIZ_ERRORS);
//            }
//            break;
//        case Const.DoorCommandType.COMMAND_SET_SIGNAL_LEVER:  //设置信号强度
//            boolean saveSuccess = jsonObject.getBoolean(Const.DoorWifi.COMMAND_WIFI_RETURN_RESULT);
////                    if (saveSuccess) {
////                        this.statusCallback.onSuccess();
////                    } else {
//////                        this.statusCallback.onFailure(Const.SIGNAL_LEVER_ERROR);
////                    }
//            break;
//        case Const.DoorCommandType.COMMAND_ADD_WHITE:   //白名单
//            boolean wSuccess = jsonObject.getBoolean(Const.CommandParams.COMMAND_WHITELIST_RESULT);
////                    if (wSuccess) {
////                        this.statusCallback.onSuccess();
////                    } else {
////                        this.statusCallback.onFailure(Const.BIZ_ERROR);
////                    }
//            break;
//        case Const.DoorCommandType.COMMAND_ADD_BLACK:   //黑名单
//            boolean bSuccess = jsonObject.getBoolean(Const.CommandParams.COMMAND_BLACKLIST_RESULT);
////                    if (bSuccess) {
////                        this.statusCallback.onSuccess();
////                    } else {
////                        this.statusCallback.onFailure(Const.BIZ_ERROR);
////                    }
//            break;
//        case Const.DoorCommandType.COMMAND_MODIFY_TIME:
//            LogTool.log(TAG, "修改系统时间点");
////                    this.statusCallback.onSuccess();
//            break;
//        case Const.DoorCommandType.COMMAND_SET_MIX_MODE:
//            LogTool.log(TAG, "设置混杂模式成功?");
//            break;
//
//    }
//} catch (Exception e) {
//        LogTool.log(TAG, e.getMessage());
//        }
//
//
//
//


}
